using Function.SkillEditor.Runtime;
using SCore.Editor.WindowDraw;
using SCore.Function.Fixed;
using UnityEditor;
using UnityEngine;

namespace Function.SkillEditor.Editor
{
    public class SkillEffectClipDraw : ISkillClipDrawer
    {
        private Transform _effectGo;
        public ParticleSystem[] _particleSys;
        private int _selectIndex;

        private void RefreshEffectGo()
        {
            if (_effectGo != null)
            {
                Object.DestroyImmediate(_effectGo);
                _effectGo = null;
            }

            var clip = _skillClip as SkillEffectClip;
            _effectGo = Object.Instantiate(clip._asset as GameObject).GetComponent<Transform>();
            _effectGo.SetPositionAndRotation(clip._pos, Quaternion.Euler(clip._rotate));
            _effectGo.localScale = clip._scale;
            _particleSys = _effectGo.GetComponentsInChildren<ParticleSystem>(false);
            RefreshEffectBind();
        }

        private void RefreshEffectBind()
        {
            var clip = _skillClip as SkillEffectClip;
            if (_effectGo != null)
            {
                if (clip._bindType == EffectPointType.Scene)
                {
                    _effectGo.SetParent(null);
                    _effectGo.SetPositionAndRotation(clip._pos, Quaternion.Euler(clip._rotate));
                    _effectGo.localScale = clip._scale;
                }
                else if (clip._bindType == EffectPointType.Avatar)
                {
                    if (SkillTimeLineSubWindow._editorGo != null)
                    {
                        _effectGo.SetParent(SkillTimeLineSubWindow._editorGo.transform.DeepFindChild(clip._bindName));
                        _effectGo.SetLocalPositionAndRotation(clip._pos, Quaternion.Euler(clip._rotate));
                        _effectGo.localScale = clip._scale;
                    }
                }
            }
        }

        public override void OnInspector(Rect rect)
        {
            base.OnInspector(rect);
            EditorGUI.BeginChangeCheck();
            var effectClip =
                EditorDrawHelp.DrawHObjetField(new Rect(rect.x, GetInspectorHeight(rect), rect.width, 20),
                    "Object", _skillClip._asset as GameObject);
            if (EditorGUI.EndChangeCheck())
            {
                _skillClip._asset = effectClip;
                RefreshEffectGo();
            }

            var clip = _skillClip as SkillEffectClip;

            EditorGUI.BeginChangeCheck();
            var bPointRect = new Rect(rect.x, GetInspectorHeight(rect), rect.width, 20);
            GUI.Label(new Rect(bPointRect.x, bPointRect.y, bPointRect.width * 0.3f, bPointRect.height), "绑定类型");
            clip._bindType = (EffectPointType)EditorGUI.EnumPopup(
                new Rect(bPointRect.x + bPointRect.width * 0.3f, bPointRect.y, bPointRect.width * 0.7f,
                    bPointRect.height),
                clip._bindType);

            if (clip._bindType == EffectPointType.Scene)
            {
                clip._pos = EditorDrawHelp.DrawVector3Field(new Rect(rect.x, GetInspectorHeight(rect), rect.width, 20),
                    "世界坐标",
                    clip._pos);
            }
            else if (clip._bindType == EffectPointType.Avatar)
            {
                _selectIndex = EditorDrawHelp.DrawPopupField(
                    new Rect(rect.x, GetInspectorHeight(rect), rect.width, 20),
                    "挂点", _selectIndex, SkillEditorConfig.Instance.GetBindContent());
                clip._pos = EditorDrawHelp.DrawVector3Field(
                    new Rect(rect.x, GetInspectorHeight(rect), rect.width, 20),
                    "偏移",
                    clip._pos);
            }

            clip._rotate = EditorDrawHelp.DrawVector3Field(new Rect(rect.x, GetInspectorHeight(rect), rect.width, 20),
                "旋转",
                clip._rotate);

            clip._scale =
                EditorDrawHelp.DrawVector3Field(new Rect(rect.x, GetInspectorHeight(rect), rect.width, 20), "缩放",
                    clip._scale);

            if (EditorGUI.EndChangeCheck())
            {
                clip._bindName = SkillEditorConfig.Instance.GetBindContent()[_selectIndex].text;
                RefreshEffectBind();
            }
        }

        public override void OnProgress(bool isPlay, fp progress)
        {
            if (_effectGo == null)
            {
                RefreshEffectGo();
            }

            if (!_effectGo.gameObject.activeSelf)
            {
                _effectGo.SetActive(true);
            }

            fp curPlayerTime =
                progress - _skillClip._startFrame * SkillRunMap.Instance.GetEOneFrameTime();
            foreach (var ps in _particleSys)
                ps.Simulate(curPlayerTime.AsFloat(), false, true, false);
        }

        public override void OnEnter(fp progress)
        {
            if (_effectGo == null)
            {
                RefreshEffectGo();
            }

            _effectGo.gameObject.SetActive(true);
        }

        public override void OnExit(bool isPlay, fp progress)
        {
            if (_effectGo == null)
            {
                RefreshEffectGo();
            }

            _effectGo.gameObject.SetActive(false);
        }

        public override void OnDisable()
        {
            if (_effectGo != null)
            {
                Object.DestroyImmediate(_effectGo.gameObject);
                _effectGo = null;
            }
        }
    }

    [TrackDrawEditor(typeof(SkillEffectTrack), typeof(SkillEffectClipDraw))]
    public class SkillEffectTrackDraw : ISkillTrackDrawer<SkillEffectTrack>
    {
        public SkillEffectTrackDraw(SkillEffectTrack skillTrack, TrackRegisterAttribute trackRegister) : base(
            skillTrack, trackRegister)
        {
        }

        protected override void DrawGroup()
        {
            EditorGUI.LabelField(new Rect(_headRect.x + 10, _headRect.y, _headRect.width, _headRect.height), "Effect");
        }
    }
}